What is apollo-server-caching?
The apollo-server-caching package provides a set of utilities for implementing caching in Apollo Server. It includes interfaces and classes for creating and managing caches, which can help improve the performance of your GraphQL server by reducing the need to repeatedly fetch the same data.
What are apollo-server-caching's main functionalities?
InMemoryLRUCache
The InMemoryLRUCache class provides an in-memory cache with a Least Recently Used (LRU) eviction policy. This is useful for caching data that is frequently accessed but can be evicted when the cache reaches its size limit.
const { InMemoryLRUCache } = require('apollo-server-caching');
const cache = new InMemoryLRUCache();
// Set a value in the cache
cache.set('key', 'value');
// Get a value from the cache
cache.get('key').then(value => console.log(value));
// Delete a value from the cache
cache.delete('key');
PrefixingKeyValueCache
The PrefixingKeyValueCache class allows you to add a prefix to all keys in a base cache. This is useful for namespacing cache entries to avoid key collisions.
const { PrefixingKeyValueCache, InMemoryLRUCache } = require('apollo-server-caching');
const baseCache = new InMemoryLRUCache();
const cache = new PrefixingKeyValueCache(baseCache, 'prefix:');
// Set a value in the cache with a prefix
cache.set('key', 'value');
// Get a value from the cache with a prefix
cache.get('key').then(value => console.log(value));
Errors and Cache
The package provides error handling mechanisms for cache operations. This ensures that your application can gracefully handle scenarios where cache operations fail.
const { InMemoryLRUCache } = require('apollo-server-caching');
const cache = new InMemoryLRUCache();
// Set a value in the cache
cache.set('key', 'value').catch(error => console.error('Error setting cache:', error));
// Get a value from the cache
cache.get('key').then(value => console.log(value)).catch(error => console.error('Error getting cache:', error));
Other packages similar to apollo-server-caching
node-cache
node-cache is a simple and fast Node.js internal caching module. It provides a straightforward API for setting, getting, and deleting cache entries. Unlike apollo-server-caching, it does not include built-in support for LRU eviction or key prefixing.
lru-cache
lru-cache is a highly efficient LRU cache implementation for Node.js. It provides more advanced configuration options compared to the InMemoryLRUCache in apollo-server-caching, such as setting a maximum age for cache entries and custom length calculation functions.
redis
redis is a powerful in-memory data structure store that can be used as a cache. It supports a wide range of data types and provides persistence options. While more complex to set up than apollo-server-caching, it offers greater scalability and flexibility.
apollo-server-caching
Implementing your own Cache
Internally, Apollo Server uses the KeyValueCache
interface to provide a caching store for the Data Sources. An in-memory LRU cache is used by default, and we provide connectors for Memcached/Redis backends.
Built with extensibility in mind, you can also implement your own cache to use with Apollo Server, in a way that best suits your application needs. It needs to implement the following interface that can be exported from apollo-server-caching
:
export interface KeyValueCache {
get(key: string): Promise<string | undefined>;
set(key: string, value: string, options?: { ttl?: number }): Promise<void>;
}
The ttl
value for the set
method's options
is specified in seconds.
Testing cache implementations
Test helpers
apollo-server-caching
exports a function that you can run within a test suite to validate your implementation. It throws on failure. If you want to test expiration, then mock out Date
and setTimeout
(probably with @sinonjs/fake-timers
) and pass a tick
can be called to advance the fake time. (If you don't pass tick
, it won't test expiration.) Other than that, it has no dependencies and can work in any test system and shouldn't require any particular build configuration to use from jest. Here's an example of how to use it with jest:
import YourKeyValueCache from '../src/YourKeyValueCache';
import { runKeyValueCacheTests } from 'apollo-server-caching';
import FakeTimers from '@sinonjs/fake-timers';
describe('YourKeyValueCache', () => {
it('run apollo-server-caching test suite', async () => {
const cache = new YourKeyValueCache();
const clock = FakeTimers.install();
try {
await runKeyValueCacheTests(cache, (ms: number) => clock.tick(ms));
} finally {
clock.uninstall();
await cache.close();
}
});
});
For more details, consult the source for apollo-server-caching
.
Running tests
Run tests with jest --verbose